#define _CRT_SECURE_NO_WARNINGS 1

#include <iostream>
#include <map>
#include <memory>

using namespace std;

//// c++98
//class NoCopy
//{
//
//private:
//	NoCopy(const NoCopy& ncp);
//	NoCopy& operator=(const NoCopy& ncp);
//};

class HeapOnly
{
public:
	static HeapOnly* CreateObj() // 需要用staic修饰，方便用::访问修饰符调用
	{ 
		return new HeapOnly;
	}
	~HeapOnly()
	{
		delete this;
	}
    
    //防拷贝
    HeapOnly(const HeapOnly& hp) = delete;
    HeapOnly& operator=(const HeapOnly& hp) = delete;

private:
	HeapOnly()
	{}
};
//
//int main()
//{
//	//HeapOnly ho; //栈区无法创建的对象
//	//static HeapOnly sho;//静态区无法创建的对象
//
//	HeapOnly* pho = HeapOnly::CreateObj();
//	
//	return 0;
//}

//class FileManager {
//public:
//    FileManager(const char* filename){
//        // 打开文件并获取文件句柄  
//        file_ = fopen(filename, "r");
//        if (!file_) {
//            throw std::runtime_error("Failed to open file");
//        }
//    }
//
//    ~FileManager() {
//        // 关闭文件句柄  
//        if (file_) {
//            fclose(file_);
//        }
//    }
//
//    // 禁用拷贝构造和赋值操作  
//    FileManager(const FileManager&) = delete;
//    FileManager& operator=(const FileManager&) = delete;
//
//    // 其他文件操作方法...  
//
//private:
//    FILE* file_;
//};
//
//int main()
//{
//    try {
//        std::unique_ptr<FileManager> fileManager = std::make_unique<FileManager>("test.txt");
//        // 使用fileManager进行文件操作...  
//    }
//    catch (const std::exception& e) {
//        // 处理异常  
//        std::cerr << "Exception: " << e.what() << std::endl;
//    }
//    return 0;
//}

//class StackOnly
//{
//public:
//	static StackOnly CreateObj()
//	{
//		StackOnly so;
//		return so;
//	}
//private:
//	StackOnly() 
//	{}
//
//	//避免使用new来拷贝构造对象
//	void* operator new(size_t n) = delete;
//};
//
//class NonInherit final
//{
//public:
//	// ...
//};
//
//int main()
//{
//	StackOnly so1 = StackOnly::CreateObj();
//
//	// new = operator new + 构造
//	//StackOnly so2 = new StackOnly(so1);
//	return 0;
//}

namespace hungry
{
	class SingleTon
	{
	public:
		//3、提供一个全局访问对象的接口
		static SingleTon& getInstance()
		{
			return _inst;
		}

	private:
		//1、禁用构造函数
		SingleTon() {}

		//2、防拷贝
		SingleTon(const SingleTon& st) = delete;
		SingleTon& operator=(const SingleTon& st) = delete;

		static SingleTon _inst;
	};

	SingleTon SingleTon::_inst; // 创建对象
}

namespace lazy
{
	class SingleTon
	{
	public:
		//3、提供一个全局访问对象的接口
		static SingleTon& getInstance()
		{
			if (_pinst == nullptr)
			{
				// 第一次调用GetInstance的时候创建单例对象
				_pinst = new SingleTon;
			}

			return *_pinst;
		}

		static void DeleteInstance()
		{
			if (_pinst)
			{
				delete _pinst;
				_pinst = nullptr;
			}
		}

		class GC
		{
		public:
			~GC()
			{
				lazy::SingleTon::DeleteInstance();
			}
		};

	private:
		//1、禁用构造函数
		SingleTon() {}


		~SingleTon()
		{
			cout << "~Singleton()" << endl;

			// map数据写到文件中
			FILE* fin = fopen("map.txt", "w");
			for (auto& e : _dict)
			{
				fputs(e.first.c_str(), fin);
				fputs(":", fin);
				fputs(e.second.c_str(), fin);
				fputs("\n", fin);
			}
		}

		//2、防拷贝
		SingleTon(const SingleTon& st) = delete;
		SingleTon& operator=(const SingleTon& st) = delete;
		
		map<string, string> _dict;
		static SingleTon* _pinst;
		static GC _gc;
	};

	SingleTon* SingleTon::_pinst = nullptr; // 创建对象
	SingleTon::GC SingleTon::_gc;
}